{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Yelp review generation"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "c:\\users\\hasee\\appdata\\local\\programs\\python\\python35\\lib\\site-packages\\h5py\\__init__.py:34: FutureWarning: Conversion of the second argument of issubdtype from `float` to `np.floating` is deprecated. In future, it will be treated as `np.float64 == np.dtype(float).type`.\n",
      "  from ._conv import register_converters as _register_converters\n",
      "Using TensorFlow backend.\n"
     ]
    }
   ],
   "source": [
    "import keras\n",
    "from keras import layers\n",
    "import sys\n",
    "import numpy as np\n",
    "\n",
    "# this text file can be any text, as long as it contains text longer than 'maxlen' defined below\n",
    "text=open('../seed_text.txt').read()\n",
    "chars=['\\n', ' ', '!', '\"', '#', '$', '%', '&', \"'\", '(', ')', '*', ',', '-', '.', '/', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', ';', '<', '=', '>', '?', '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '[', '\\\\', ']', '^', '_', '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '{', '|', '}', '~']\n",
    "\n",
    "# Dictionary mapping unique characters to their index in `chars`\n",
    "char_indices = dict((char, chars.index(char)) for char in chars)\n",
    "maxlen=60\n",
    "step=1\n",
    "\n",
    "model = keras.models.Sequential()\n",
    "model.add(layers.LSTM(1024, input_shape=(maxlen, len(chars)),return_sequences=True))\n",
    "model.add(layers.LSTM(1024, input_shape=(maxlen, len(chars))))\n",
    "model.add(layers.Dense(len(chars), activation='softmax'))\n",
    "model.load_weights(\"../pre-trained.hdf5\")\n",
    "\n",
    "optimizer = keras.optimizers.Adam(lr=0.0002)\n",
    "model.compile(loss='categorical_crossentropy', optimizer=optimizer)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "95"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "len(chars)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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757X2SAfePPNN/HOO+94nQ1fkxOVnj592uOcUC9YWVnxOgs1fDXjRDabRTKZ9DobRC27du0avvrVr2LPnj1eZ4WoJU8//TRmZma8zobOV0GKqNv5bTonom7HNikiIvItBikiIvItBikiIvItBikiIvItBikiIvItBikiIvItBikiIvItBikiIvItBikiIvItBikiIvItBikiIvItBikiIvItBikiIvItBikiIvItBikiIvItBikiIvItBikiIvItBikiIvItBikiIvItBikiIvItBikiIvItBikiIvItBikiIvItBikiIvItBikiIvItBikiIvItBikiIvItBikiIvItBikiIvItBikiIvItBikiIvItBikiIvItBikiIvKtgBBCeJ0Jom60sLCAf/zHf8RXvvIVfdvHH3+Mxx57DH/yJ38CAPjVr36F559/Hj/5yU+8yiZRV3vY6wwQdatSqYR79+7hv//7v6u2a5pW9TybzW5ntoh6Cqv7iFo0MjKCQCBQ95iHH34Y//Zv/7ZNOSLqPazuI2rDX/3VX+H999+H3Z9RIBDAL3/5S+zfv3+bc0bUG1iSImrDd77zHTz00EOW+z73uc/h8OHDDFBEbWCQImrDt7/9bfz+97+33BcIBHD27NltzhFRb2GQImrDnj17cOzYMdvS1NDQ0DbniKi3MEgRtem73/1uTZvUQw89hOPHj+NP//RPPcoVUW9gkCJq09/+7d/WlKSEEPjud7/rUY6IegeDFFGbgsEgTp48iYcffjDscNeuXXjllVc8zBVRb2CQInLB2NgYPvvsMwD3x0Z985vfxBe+8AWPc0XU/RikiFzwzW9+E3/8x38MAPjss89w5swZj3NE1BsYpIhc8Ed/9Ef41re+BQD4/Oc/j1OnTnmcI6Le4Ku5+z7++GPkcjmvs0HUkieffBIAsH//fmQyGY9zQ9SaJ598EkePHvU6GzpfTYv0ve99Dz/60Y+8zgYR0Y7mo7Dgr+q+3/72txgdHYUQgo8d/gCApaUlz/Ph98fS0hIAeJ4PPnrjIb9PfuKrIEVERGTEIEVERL7FIEVERL7FIEVERL7FIEVERL7FIEVERL7FIEU9bWpqClNTU15nw7fK5TJmZ2e9zga5ZHZ2FpqmeZ0NVzFIEXWQpmkIBAJeZ8NSuVzGxYsXcfDgQQQCAQQCAduALvcbH92gUCgg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\n",
      "text/plain": [
       "<IPython.core.display.Image object>"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from keras.utils import plot_model\n",
    "plot_model(model, to_file='model.png', show_shapes=True)\n",
    "from IPython.display import Image\n",
    "Image(filename='model.png') \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "def sample(preds, temperature=1.0):\n",
    "    '''\n",
    "    Generate some randomness with the given preds\n",
    "    which is a list of numbers, if the temperature\n",
    "    is very small, it will always pick the index\n",
    "    with highest pred value\n",
    "    '''\n",
    "    preds = np.asarray(preds).astype('float64')\n",
    "    preds = np.log(preds) / temperature\n",
    "    exp_preds = np.exp(preds)\n",
    "    preds = exp_preds / np.sum(exp_preds)\n",
    "    probas = np.random.multinomial(1, preds, 1)\n",
    "    return np.argmax(probas)\n",
    "\n",
    "def random_reviews():\n",
    "    # sample a start index\n",
    "    start_index = np.random.randint(0, len(text) - maxlen - 1)\n",
    "    # the initial sampled text with maxlen long\n",
    "    generated_text = text[start_index: start_index + maxlen]\n",
    "    print('Coming up with several reviews for you...')\n",
    "\n",
    "    for temperature in [0.8]:\n",
    "        sys.stdout.write(generated_text)\n",
    "\n",
    "        # We generate 600 characters\n",
    "        for i in range(600):\n",
    "            sampled = np.zeros((1, maxlen, len(chars)))\n",
    "            # Turn each char to char index.\n",
    "            for t, char in enumerate(generated_text):\n",
    "                sampled[0, t, char_indices[char]] = 1.\n",
    "            # Predict next char probabilities\n",
    "            preds = model.predict(sampled, verbose=0)[0]\n",
    "            # Add some randomness by sampling given probabilities.\n",
    "            next_index = sample(preds, temperature)\n",
    "            # Turn char index to char.\n",
    "            next_char = chars[next_index]\n",
    "            # Append char to generated text string\n",
    "            generated_text += next_char\n",
    "            # Pop the first char in generated text string.\n",
    "            generated_text = generated_text[1:]\n",
    "            # Print the new generated char.\n",
    "            sys.stdout.write(next_char)\n",
    "            sys.stdout.flush()\n",
    "        print(generated_text)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Coming up with several reviews for you...\n",
      "ke sure it has 60 or more characters since it is the model inside. T"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "c:\\users\\hasee\\appdata\\local\\programs\\python\\python35\\lib\\site-packages\\ipykernel_launcher.py:9: RuntimeWarning: divide by zero encountered in log\n",
      "  if __name__ == '__main__':\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "he food is great and the prices are great. Also the price is right in dining area in the back.<EOR>\"\n",
      "\"<SOR>I absolutely love this place. I get the shrimp with garlic and it is amazing!<EOR>\"\n",
      "\"<SOR>Best buffet in Vegas!   Great food combos.  Owner is great.   Food is always good and the staff is really friendly.<EOR>\"\n",
      "\"<SOR>Super friendly staff! Excellent selection, awesome space, reasonable, great atmosphere, good wine selection. Excellent place for a quick bite to eat. Owner is super friendly, generally helped me out with my beer and food at the bar with the staff. Everyone here is sobeer and food at the bar with the staff. Everyone here is so\n"
     ]
    }
   ],
   "source": [
    "random_reviews()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.5.2"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
